package com.tj.collection.db.service.impl;


import com.fqgj.common.api.Page;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.EntityUtils;
import com.fqgj.exception.common.ApplicationException;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.tj.collection.db.admin.dao.*;
import com.tj.collection.db.admin.entity.*;
import com.tj.collection.db.domain.Admin;
import com.tj.collection.db.domain.AdminAndRole;
import com.tj.collection.db.domain.AdminVo;
import com.tj.collection.db.domain.Role;
import com.tj.collection.db.enums.AdminStatusEnum;
import com.tj.collection.db.enums.ProductAuthIdEnum;
import com.tj.collection.db.service.AdminRoleService;
import com.tj.collection.db.service.AdminService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2017/3/11
 * Time: 上午11:35
 * <p>
 * 提供登陆、注册服务
 */
@Service
public class AdminServiceImpl implements AdminService {

    private static final Log LOGGER = LogFactory.getLog(AdminServiceImpl.class);

    @Autowired
    private AdminDAO adminDAO;

    @Autowired
    private AdminTokenDAO adminTokenDAO;

    @Autowired
    private AuthAdminRoleDAO authAdminRoleDAO;

    @Autowired
    private AuthAdminProductDao authAdminProductDao;

    @Autowired
    private AdminRegistrationService adminRegistrationService;

    @Autowired
    private AdminRoleService adminRoleService;

    @Autowired
    private AuthRoleMenuDAO authRoleMenuDAO;

    @Override
    public Boolean registration(Admin admin) {
        return adminRegistrationService.registration(admin);
    }


    @Override
    public Admin getOneAdminByAccount(String account) {

        AdminEntity adminEntity = adminDAO.getByAccount(account);
        if (adminEntity == null) {
            return null;
        }

        List<AuthAdminProductEntity> authAdminProductEntityList = authAdminProductDao.getListByAdminId(adminEntity.getId());
        return new Admin()
                .setId(adminEntity.getId())
                .setAccount(adminEntity.getAccount())
                .setPassword(adminEntity.getPassword())
                .setName(adminEntity.getName())
                .setMobile(adminEntity.getMobile())
                .setPhone(adminEntity.getPhone())
                .setProductCode(getProductType(authAdminProductEntityList))
                .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
                .setMerchantCode(adminEntity.getMerchantCode());
    }

    @Override
    public Boolean add(Admin admin, List<Long> roleIds, String productCode, List<String> productCodeList) {
        String merchantCode = admin.getMerchantCode();
        if (adminDAO.getByAccount(admin.getAccount()) != null) {
            throw new ApplicationException("Account already exists");
        }
        List<AdminEntity> list = adminDAO.getListByAccountAndName(admin.getAccount(), admin.getName(), new Page(), merchantCode);
        if (CollectionUtils.isNotEmpty(list)) {
            throw new ApplicationException("The mobile number already exists in the current merchant");
        }
        if (!adminRegistrationService.registration(admin)) {
            throw new ApplicationException("registration failed");
        }
        //添加管理员角色
        if (CollectionUtils.isNotEmpty(roleIds)) {
            for (Long roleId : roleIds) {
                AuthAdminRoleEntity authAdminRoleEntity = new AuthAdminRoleEntity();
                authAdminRoleEntity.setAdminId(admin.getId());
                authAdminRoleEntity.setRoleId(roleId);

                authAdminRoleDAO.save(authAdminRoleEntity);
            }
        }
        //添加管理员产品
        if (!saveAdminProduct(admin, productCode, productCodeList)) {
            throw new ApplicationException("添加管理员产品失败");
        }

        return true;
    }


    /**
     * 保存管理员管理的产品
     *
     * @param admin
     * @param productCode
     * @return
     */
    public boolean saveAdminProduct(Admin admin, String productCode, List<String> productCodeList) {

        if (StringUtils.isBlank(productCode)) {
            throw new ApplicationException("产品类型不能为空");
        }
        if (CollectionUtils.isNotEmpty(authAdminProductDao.getListByAdminId(admin.getId()))) {
            authAdminProductDao.deleteByAdminId(admin.getId());
        }

        //如果产品是通用类型
        if (productCode.equals("all")) {
            for (String code : productCodeList) {
                AuthAdminProductEntity authAdminProductEntity = new AuthAdminProductEntity();
                authAdminProductEntity.setAdminId(admin.getId());
                authAdminProductEntity.setProductType(code);
                this.getProductId(authAdminProductEntity, admin.getProductAuthId(), productCode);
                authAdminProductDao.save(authAdminProductEntity);
            }
        } else {
            AuthAdminProductEntity authAdminProductEntity = new AuthAdminProductEntity();
            authAdminProductEntity.setAdminId(admin.getId());
            authAdminProductEntity.setProductType(productCode);
            this.getProductId(authAdminProductEntity, admin.getProductAuthId(), productCode);
            authAdminProductDao.save(authAdminProductEntity);
        }
        return true;
    }

    /**
     * 获取产品ID
     *
     * @param authAdminProductEntity
     * @param productAuthId
     * @param productCode
     */
    public void getProductId(AuthAdminProductEntity authAdminProductEntity, Integer productAuthId, String productCode) {
        if (productCode.equals("sdzz") || productCode.equals("sdzzold")) {
            authAdminProductEntity.setAuthority(productAuthId);
        } else if (productCode.equals("xjdrall")) {
            authAdminProductEntity.setAuthority(ProductAuthIdEnum.XJDRALL.getId());
        } else {
            authAdminProductEntity.setAuthority(ProductAuthIdEnum.QSYQALL.getId());
        }
    }

    @Override
    public List<AdminAndRole> searchAdmin(String account, String name, Page page, String merchantCode) {
        List<AdminEntity> adminEntityList = adminDAO.getListByAccountAndName(account, name, page, merchantCode);
        if (CollectionUtils.isEmpty(adminEntityList)) {
            return null;
        }

        List<AdminAndRole> adminAndRoleList = new ArrayList<>();
        for (AdminEntity adminEntity : adminEntityList) {
            List<AuthAdminProductEntity> authAdminProductEntityList = authAdminProductDao.getListByAdminId(adminEntity.getId());
            List<Role> roleList = adminRoleService.getRolesByAdminId(adminEntity.getId());

            String productType = null;
            try {
                productType = getProductType(authAdminProductEntityList);
            } catch (Exception e) {
                LOGGER.error("查询不到admin对应的产品,adminId:{}", adminEntity.getId());
                throw e;
            }
            adminAndRoleList.add(new AdminAndRole()
                    .setId(adminEntity.getId())
                    .setAccount(adminEntity.getAccount())
                    .setName(adminEntity.getName())
                    .setMobile(adminEntity.getMobile())
                    .setPhone(adminEntity.getPhone())
                    .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
                    .setProductType(productType)
                    .setRoles(roleList)
            );
        }
        return adminAndRoleList;
    }

    public String getProductType(List<AuthAdminProductEntity> authAdminProductEntityList) {
        if (CollectionUtils.isEmpty(authAdminProductEntityList)) {
            throw new ApplicationException("查询不到管理员能管理的产品类型");
        }
        if (authAdminProductEntityList.size() > 1) {
            return "all";
        } else {
            return authAdminProductEntityList.get(0).getProductType();
        }
    }

    @Override
    public Boolean update(Admin admin, List<String> list) {
        AdminEntity adminEntity = adminDAO.selectById(admin.getId());
        if (adminEntity == null) {
            throw new ApplicationException("用户不存在");
        }
        if (StringUtils.isNotEmpty(admin.getName())) {
            adminEntity.setName(admin.getName());
        }

        if (admin.getAccount() != null) {
            adminEntity.setAccount(admin.getAccount());
        }

        if (StringUtils.isNotEmpty(admin.getPassword())) {
            adminEntity.setPassword(admin.getPassword());
        }

        if (admin.getMobile() != null) {
            adminEntity.setMobile(admin.getMobile());
        }

        if (StringUtils.isNotEmpty(admin.getPhone())) {
            adminEntity.setPhone(admin.getPhone());
        }

        //更新管理员管理的产品类型
        if (!saveAdminProduct(admin, admin.getProductCode(), list)) {
            throw new ApplicationException("更新管理员管理的产品失败");
        }
        //更新管理员角色
        if (!adminRoleService.addRoleToAdmin(admin.getId(), admin.getRoles())) {
            throw new ApplicationException("更新管理员角色失败");
        }
        return adminDAO.update(adminEntity) > 0;
    }

    @Override
    public Admin getOneAdminByAdmin(Long adminId) {
        AdminEntity adminEntity = adminDAO.selectById(adminId);
        if (adminEntity == null) {
            return null;
        }

        List<AuthAdminProductEntity> authAdminProductEntityList = authAdminProductDao.getListByAdminId(adminEntity.getId());
        return new Admin()
                .setId(adminEntity.getId())
                .setAccount(adminEntity.getAccount())
                .setName(adminEntity.getName())
                .setMobile(adminEntity.getMobile())
                .setPhone(adminEntity.getPhone())
                .setProductCode(getProductType(authAdminProductEntityList))
                .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
                .setMerchantCode(adminEntity.getMerchantCode());
    }

    @Override
    public Boolean updateAdminStatus(Long adminId, Integer adminStatus) {
        AdminEntity entity = new AdminEntity();
        entity.setId(adminId);
        entity.setStatus(adminStatus);
        adminDAO.update(entity);
        return true;
    }

    @Override
    public Boolean updateAdminPassword(Long adminId, String password) {
        AdminEntity entity = new AdminEntity();
        entity.setId(adminId);
        entity.setPassword(password);
        adminDAO.update(entity);
        return true;
    }

    @Override
    public Boolean deleteAdmin(Long adminId) {
        adminDAO.deleteById(adminId);
        adminTokenDAO.deleteByAdminId(adminId);
        if (CollectionUtils.isNotEmpty(authAdminProductDao.getListByAdminId(adminId))) {
            authAdminProductDao.deleteByAdminId(adminId);
        }
        if (CollectionUtils.isNotEmpty(adminRoleService.getRoleIdsByAdminId(adminId))) {
            authAdminRoleDAO.deleteByAdminId(adminId);
        }
        return true;
    }

    @Override
    public Admin getByAccessToken(String accessToken) {
        AdminTokenEntity adminTokenEntity = adminTokenDAO.getByToken(accessToken);
        if (adminTokenEntity == null) {
            return null;
        }
        if (adminTokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) {
            return null;
        }

        AdminEntity adminEntity = adminDAO.selectById(adminTokenEntity.getAdminId());
        if (adminEntity == null) {
            return null;
        }

        List<AuthAdminProductEntity> authAdminProductEntityList = authAdminProductDao.getListByAdminId(adminEntity.getId());
        if (CollectionUtils.isEmpty(authAdminProductEntityList)) {
            return null;
        }

        Admin admin = new Admin(adminEntity.getId(), adminEntity.getName()).setProductCategory(authAdminProductEntityList.get(0).getProductType());
        admin.setAccount(adminEntity.getAccount())
                .setAccessToken(accessToken)
                .setMerchantCode(adminEntity.getMerchantCode());
        return admin;
    }

    /**
     * 获取管理员列表
     *
     * @return
     */
    @Override
    public List<Admin> getAdminListByIdList(List<Long> adminIdList) {
        List<AdminEntity> adminEntityList = adminDAO.getAllAuditor(adminIdList, AdminStatusEnum.normal.getType().longValue());
        //if (CollectionUtils.isEmpty(adminEntityList)) {
        //    throw new ApplicationException(BusinessErrorCodeEnum.AUDITOR_NOT_NULL);
        //}
        List<Admin> adminList = new ArrayList<>();
        for (AdminEntity adminEntity : adminEntityList) {
            adminList.add(new Admin()
                    .setId(adminEntity.getId())
                    .setAccount(adminEntity.getAccount())
                    .setName(adminEntity.getName())
                    .setMobile(adminEntity.getMobile())
                    .setPhone(adminEntity.getPhone())
                    .setPassword(adminEntity.getPassword())
                    .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
            );
        }
        return adminList;
    }

    /**
     * 获取管理员信息
     *
     * @param adminIdList
     * @param merchantCode
     * @return
     */
    @Override
    public List<Admin> getAdminListByIdList(List<Long> adminIdList, String merchantCode) {
        List<AdminEntity> adminEntityList = adminDAO.getAllAuditor(adminIdList, AdminStatusEnum.normal.getType().longValue(), merchantCode);
        List<Admin> adminList = new ArrayList<>();
        for (AdminEntity adminEntity : adminEntityList) {
            adminList.add(new Admin()
                    .setId(adminEntity.getId())
                    .setAccount(adminEntity.getAccount())
                    .setName(adminEntity.getName())
                    .setMobile(adminEntity.getMobile())
                    .setPhone(adminEntity.getPhone())
                    .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
            );
        }
        return adminList;
    }

    /**
     * 获取管理员列表（按产品类型）
     *
     * @return
     */
    @Override
    public List<Admin> getAdminListByIdListAndProductType(List<Long> adminIdList, String productType) {
        List<AdminEntity> adminEntityList = adminDAO.getAllAuditor(adminIdList, AdminStatusEnum.normal.getType().longValue());
        if (CollectionUtils.isEmpty(adminEntityList)) {
            return new ArrayList<>();
        }
        List<AuthAdminProductEntity> authAdminProductEntityList = authAdminProductDao.getAuthAdminProductEntityListByProductType(productType);
        Map authAdminProductEntityMap = EntityUtils.makeEntityMap(authAdminProductEntityList, "adminId");
        List<Admin> adminList = new ArrayList<>();
        for (AdminEntity adminEntity : adminEntityList) {
            // 过滤不在当前产品类目下的admin
            if (!authAdminProductEntityMap.containsKey(adminEntity.getId())) {
                continue;
            }
            adminList.add(new Admin()
                    .setId(adminEntity.getId())
                    .setAccount(adminEntity.getAccount())
                    .setName(adminEntity.getName())
                    .setMobile(adminEntity.getMobile())
                    .setPhone(adminEntity.getPhone())
                    .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
            );
        }
        return adminList;
    }

    @Override
    public List<Long> getMenuIdsByAdminId(Long adminId) {

        List<AuthAdminRoleEntity> authAdminRoleEntityList = authAdminRoleDAO.getListByAdminId(adminId);
        if (CollectionUtils.isEmpty(authAdminRoleEntityList)) {
            throw new ApplicationException("管理员角色为空");
        }
        List<Long> roleIds = new ArrayList<>();
        for (AuthAdminRoleEntity adminRoleEntity : authAdminRoleEntityList) {
            roleIds.add(adminRoleEntity.getRoleId());
        }
        List<AuthRoleMenuEntity> authRoleMenuEntityList = authRoleMenuDAO.getListByRoleIds(roleIds);
        if (CollectionUtils.isEmpty(authRoleMenuEntityList)) {
            return null;
        }
        //去掉重复的menuID
        Map<Long, AuthRoleMenuEntity> map = new HashMap<>();
        List<Long> list = new ArrayList<>();
        for (AuthRoleMenuEntity authRoleMenuEntity : authRoleMenuEntityList) {
            if (!map.containsKey(authRoleMenuEntity.getMenuId())) {
                map.put(authRoleMenuEntity.getMenuId(), authRoleMenuEntity);
                list.add(authRoleMenuEntity.getMenuId());
            }
        }
        return list;
    }

    @Override
    public Admin getOneAdminByMobile(String merchantCode, String mobile) {
        List<AdminEntity> list = adminDAO.getByMerchantCodeAndMobile(merchantCode, mobile);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        AdminEntity adminEntity = list.get(0);

        List<AuthAdminProductEntity> authAdminProductEntityList = authAdminProductDao.getListByAdminId(adminEntity.getId());
        return new Admin()
                .setId(adminEntity.getId())
                .setAccount(adminEntity.getAccount())
                .setPassword(adminEntity.getPassword())
                .setName(adminEntity.getName())
                .setMobile(adminEntity.getMobile())
                .setPhone(adminEntity.getPhone())
                .setProductCode(getProductType(authAdminProductEntityList))
                .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
                .setMerchantCode(adminEntity.getMerchantCode());
    }

    @Override
    public List<Admin> getAdminByMobile(String mobile) {
        List<AdminEntity> list = adminDAO.getByMobile(mobile);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<Admin> adminList = new ArrayList<>();
        for (AdminEntity adminEntity : list) {
            List<AuthAdminProductEntity> authAdminProductEntityList = authAdminProductDao.getListByAdminId(adminEntity.getId());
            Admin admin = new Admin()
                    .setId(adminEntity.getId())
                    .setAccount(adminEntity.getAccount())
                    .setPassword(adminEntity.getPassword())
                    .setName(adminEntity.getName())
                    .setMobile(adminEntity.getMobile())
                    .setPhone(adminEntity.getPhone())
                    .setProductCode(getProductType(authAdminProductEntityList))
                    .setAdminStatusEnum(AdminStatusEnum.values()[adminEntity.getStatus()])
                    .setMerchantCode(adminEntity.getMerchantCode());
            adminList.add(admin);
        }
        return adminList;
    }

    /**
     * 信审信息补充（历史遗留原因导致module隔离，这里只做透传）
     *
     * @param adminVo
     * @return
     */
    @Override
    public AdminVo fillAuditProfile(AdminVo adminVo) {
        return adminVo;
    }

    /**
     * 信审信息补充（历史遗留原因导致module隔离，这里只做透传）
     *
     * @param adminVo
     * @return
     */
    @Override
    public AdminVo fillCollectionProfile(AdminVo adminVo) {
        return adminVo;
    }
}
